﻿using MiniFox.Components;
using MiniFox.Infrastructure;
using MiniFox.Platform.Applications.Configurations;
using MiniFox.Platform.Exceptions;
using MiniFox.Web;
using System.Security.Claims;
using System.Security.Principal;
using System.Text.RegularExpressions;

namespace MiniFox.Platform.Applications.Auth
{
    /// <summary>
    /// 
    /// </summary>
    [AutoRegister, SpareComponent(typeof(ApiAuthClient))]
    public class ApiAuthClient : AuthorizationClient
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="stateManagement"></param>
        public ApiAuthClient(IAuthStateManagement stateManagement) : base(stateManagement)
        {
        }
        /// <summary>
        /// 
        /// </summary>
        [AutoConfigure]
        public ApiAuthClientConfiguration Configuration
        {
            get;
            set;
        }

        #region miniAuth config values

        /// <summary>
        /// 
        /// </summary>
        public Uri VerifyTokenUrl
        {
            get { return new Uri(this.Configuration.FullVerifyTokenUrl); }
        }

        #endregion

        /// <summary>
        /// 
        /// </summary>
        public string AccessToken
        {
            get
            {
                return this.StateManagement.Token;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        protected override SystemIdentity GetIdentity()
        {
            return GetIdentity(this.AccessToken);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="accessToken"></param>
        /// <returns></returns>
        protected internal override SystemIdentity GetIdentity(string accessToken)
        {
            var identity = this.StateManagement.CurrentIdentity;
            if (identity == null)
            {
                var response = this.VerifyTokenUrl.HttpGet<Response<ApplicationIdentity>>(new { accessToken });
                if (response.Success)
                {
                    identity = response.Data;
                    this.StateManagement.CurrentIdentity = identity;
                }
                else
                {
                    string msg = string.IsNullOrEmpty(response.Message) ? Resources.ResMessage.ERR_Unauthorized : response.Message;
                    var e = new PlatformException(response.Code);
                    this.WriteFatalLog(e);
                    throw e;
                }
            }

            return identity;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public override bool IsExceptionUrl(string url)
        {
            return this.Configuration.ExceptionUrls.Any(str => string.Equals(url, str, StringComparison.OrdinalIgnoreCase) || Regex.IsMatch(url, str, RegexOptions.IgnoreCase));
        }

        /// <summary>
        /// 验证当前令牌状态
        /// </summary>
        /// <returns></returns>
        public override bool VerifyTokenState()
        {
            var validState = (string.IsNullOrEmpty(this.StateManagement.Token) || this.Identity == null);
            if (!validState)//校验失败时，清除状态
            {
                this.ClearState();
            }

            return validState;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="requestUrl"></param>
        /// <returns></returns>
        public override string[] GetRoles(string requestUrl)
        {
            return new string[0];
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="requestUrl"></param>
        /// <param name="entryUrl"></param>
        /// <returns></returns>
        public override string[] GetRoles(string requestUrl, string entryUrl)
        {
            return new string[0];
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        protected override ClaimsPrincipal CreatePrincipal()
        {
            return new GenericPrincipal(this.Identity, new string[0]);
        }

    }
}
